﻿using System;
using System.Collections.Generic;
using System.Xml;

using Yawf.Core.Logs;
using Yawf.Core.Xml;
using Yawf.Security;
using Yawf.Security.Entities;
using Yawf.Web.Managers.Modules;
using Yawf.Web.Utils;

namespace Yawf.Web.Managers {
	public class ModuleModelManager : IModelInvokerManager {
		// Private fields
		private IDictionary<String,IModule> modules;

		// Properties
		private IDictionary<String,IModule> Modules { get { return modules; } set { modules = value; } }

		/// <summary>
		/// This method will read a resource VCG XML file and for each
		/// child inside <model /> tag this method will try to find a IModule
		/// which has been registered to handle the spefici tag. This method will
		/// then call execute method of IModlue found
		/// </summary>
		/// <param name="requestWrapper">RequestWrapper object</param>
		/// <param name="responseWrapper">ResponseWrapper object</param>
		/// <param name="resource">path to resource that has been requested</param>
		/// <param name="user">currently logged on user, could be null</param>
		public void ProcessModel(RequestWrapper requestWrapper,ResponseWrapper responseWrapper,String resource,IUser user) {
			XmlNodeList nodes;
			XmlDocument xmlDoc;
			XmlElement tmpElem;
			XmlNode content;
			IModule module;
			int i;

			// Read xml
			xmlDoc = XmlUtils.ReadXmlDocument(resource);
			if (xmlDoc != null && xmlDoc.DocumentElement != null) {
				content = xmlDoc.DocumentElement.SelectSingleNode("model");
				if (content is XmlElement) {
					// Loop through all nodes and call appropiate module 
					nodes = content.ChildNodes;
					for (i = 0; nodes != null && i < nodes.Count; i++) {
						content = nodes[i];
						if (content is XmlElement) {
							// Try to find approiate module by tag
							module = GetModuleByTag(content.Name);
							if (module != null) {
								// Get input object
								tmpElem = (XmlElement)content;

								// execute module
								module.Execute(tmpElem,requestWrapper,responseWrapper,user);
							} else {
								Log.WarnMessage(this.GetType(),"Tag <" + content.Name + "> in resource " + resource + " is not managed by any module");
							}

						}
					}
				}
			}
		}									// ProcessModel

		/// <summary>
		/// Gets a IModule that has registred to handle certain Xml tag
		/// </summary>
		/// <param name="tag">Xml Tag to get IModule for</param>
		/// <returns>IModule if there is a registration for Xml tag, null if not</returns>
		private IModule GetModuleByTag(String tag) {
			IModule tmpModule = null;

			if (Modules != null && Modules.ContainsKey(tag)) {
				tmpModule = Modules[tag];
			}

			return tmpModule;
		}										// GetModuleByTag
	}
}
